package com.wangjie.order.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.wangjie.common.R;
import com.wangjie.order.entity.Order;
import com.wangjie.order.properties.OrderProperties;
import com.wangjie.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

@Slf4j
@RestController
@RequestMapping("/order")
@RefreshScope
public class OrderController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderProperties orderProperties;

    @Value("${order.timeout}")
    private String orderTimeout;

    @Value("${order.auto-confirm}")
    private String orderAutoConfirm;

    @GetMapping("/config")
    public String config() {
        return "order.timeout=" + orderTimeout + " order.auto-confirm=" + orderAutoConfirm;
    }

    @GetMapping("/info")
    public String info() {
        return "order.timeout=" + orderProperties.getTimeout() + " order.auto-confirm=" + orderProperties.getAutoConfirm();
    }

    @GetMapping("/data")
    public String data() {
        return "order.timeout=" + orderProperties.getTimeout() + " order.auto-confirm=" + orderProperties.getAutoConfirm() + " order.db_url=" + orderProperties.getDbUrl();
    }

    /**
     * 普通创建订单
     */
    @GetMapping("/create")
    public Order createOrder(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId) {
        Order order = orderService.createOrder(userId, productId);
        return order;
    }

    /**
     * 秒杀创建订单
     */
    @GetMapping("/seckill")
    // 目前 Sentinel 自带的 adapter 仅 Dubbo 方法埋点带了热点参数, 其它适配模块(如 Web)默认不支持热点规则, 可通过自定义埋点方式指定新的资源名并传入希望的参数
    // 注意自定义埋点的资源名不要和适配模块生成的资源名重复, 否则会导致重复统计
    @SentinelResource(value = "seckill-order", fallback = "seckillFallback")
    public Order seckill(@RequestParam("userId") Long userId, @RequestParam("productId") Long productId) {
        Order order = orderService.createOrder(userId, productId);
        order.setId(Long.MAX_VALUE);
        return order;
    }

    public Order seckillFallback(Long userId, Long productId, Throwable e) {
        Order order = new Order();
        order.setId(0L);
        order.setTotalAmount(new BigDecimal("0"));
        order.setUserId(userId);
        order.setNickName("未知用户");
        order.setAddress("异常信息: " + e.getClass());
        return order;
    }

    @GetMapping("/writeDb")
    public R writeDb() {
        return R.ok("writeDb success...");
    }

    @GetMapping("/readDb")
    public R readDb() {
        log.info("readDb...");
        return R.ok("readDb success...");
    }
}
